package com.emip.util.report;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.emip.bean.ExpFlagBean;
import com.emip.bean.SiteItemBean;
import com.emip.bean.Store;
import com.emip.util.report.impl.AverageComput;
import com.emip.util.report.impl.CommonComput;

public class Statistics {

	public static String VALID = "valid";
	public static String UNVALID = "unvalid";
	public static String EMPTY = "empty";
	
	public static String ZZ = "P";
	public static String XX = "P";
	public static String YY = "P";
	public static String HL = "HL";
	public static String EXCEED_FLAG = "HL";
	public static String EXCEPTION_FLAG = "P";
	
	private Map<String, Comput> itemComputs;
	private Map<String, Comput> unvalidItemComputs;
	private Map<String, Integer> counts;
	private Map<String, SiteItemBean> siteItemMap;
	private Map<String, Boolean> flagMap;
	
	private List<Comput> computs;
	private List<SiteItemBean> siteItems;
	
	
	public Statistics(List<Comput> computList, List<SiteItemBean> siteItemList, List<ExpFlagBean> flags) {
		counts = new HashMap<String, Integer>();
		siteItemMap = new HashMap<String, SiteItemBean>();
		flagMap = new HashMap<String, Boolean>();
		siteItems = siteItemList;
		
		if (flags != null) {
			for (int i = 0; i < flags.size(); i++) {
				ExpFlagBean flag = flags.get(i);
				Boolean inStat = flag.getInStat() != null 
						&& flag.getInStat().equalsIgnoreCase("T");
				flagMap.put(flag.getFlag().trim(), inStat);
			}
		}
		
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			siteItemMap.put(siteItem.getSite().getId() + "_" + siteItem.getItem().getId(), siteItems.get(i));
		}
		
		if (computList != null && computList.size() > 0) {
			computs = computList;
		} else {
			computs = new ArrayList<Comput>();
			computs.add(new AverageComput());
		}
		
		init();
	}
	
	public void init() {
		itemComputs = new HashMap<String, Comput>();
		unvalidItemComputs = new HashMap<String, Comput>();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			for (int j = 0; j < computs.size(); j++) {
				Comput comput = computs.get(j);
				if (comput instanceof CommonComput) continue;
				String key = siteItem.getSite().getId() + "_" + siteItem.getItem().getId();
				counts.put(key, 0);
				key = comput.getComputName() + "_" + key;
				itemComputs.put(key, comput.newInstance());
				comput = comput.newInstance();
				comput.setFlag(Statistics.EXCEPTION_FLAG);
				unvalidItemComputs.put(key, comput);
			}
		}
	}
	
	public <T> List<Store> comput(List<T> stores) {
		List<Store> datas = new ArrayList<Store>();
//		Comput comput;
		for (int i = 0; i < stores.size(); i++) {
			Store store = (Store) stores.get(i);
			String key = store.getSiteID() + "_" + store.getItemID();
			Integer count = counts.get(key);
			if (count == null) continue;
			counts.put(key, count + 1);
			Double value = null;
			//判断值是否合法
			try {
				if (store.getValue() == null) continue;
				value = Double.parseDouble(store.getValue());
			} catch(java.lang.NumberFormatException e) {
				store.setFlag(XX);
				datas.add(store);
				continue;
			}
			
			//计算
			SiteItemBean siteItem = siteItemMap.get(key);
			//检查flag是否为合法值
			String storeFlag = store.getFlag();
			Boolean ifRightFlag = (storeFlag == null)
					|| storeFlag.trim().equals("") 
					|| (flagMap.get(storeFlag.trim()) != null 
					&& flagMap.get(storeFlag.trim()));
			//判断value是否在合法范围内
			Boolean ifRightValue = siteItem.geteMaxValue() == 0 
					|| (
						value.compareTo(siteItem.geteMaxValue()) <= 0 
						&& value.compareTo(siteItem.geteMinValue()) >= 0
					);
			
			if (ifRightFlag && ifRightValue) {
				if (value.compareTo(siteItem.getOverMaxValue()) >= 0 
						|| value.compareTo(siteItem.getOverMinValue()) <= 0) {
					store.setFlag(EXCEED_FLAG);
				}
				putinComputs(itemComputs, key, store);
			}  else {//异常值计算
				store.setFlag(EXCEPTION_FLAG);
				datas.add(store);
				putinComputs(unvalidItemComputs, key, store);
			}
		}
		
		return datas;
	}
	
	private void putinComputs(Map<String, Comput> itemComputs, String key, Store store) {
		for (int j = 0; j < computs.size(); j++) {
			Comput comput = itemComputs.get(computs.get(j).getComputName() + "_" + key);
			if (comput != null) {
				comput.put(store);
			}
		}
	}
	
	
	public Map<String, Comput> getResults() {
		Comput comput;
		//计算有效率
		CommonComput validComput = new CommonComput();
		validComput.setLabel("有效率");
		validComput.setComputName("ValidComput");
		
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			String key = siteItem.getSite().getId() + "_" + siteItem.getItem().getId();
			Integer count = counts.get(key); 
			if (count == null || count == 0) continue;
			comput = itemComputs.get(computs.get(0).getComputName() + "_" + key);
			Integer vcount = comput.getCount();
			if (vcount == 0) {
				for (int j = 0; j < computs.size(); j++) {
					comput = unvalidItemComputs.get(computs.get(j).getComputName() + "_" + key);
					itemComputs.put(computs.get(j).getComputName() + "_" + key, comput);
				}
			} 
			CommonComput validComputTemp = (CommonComput) validComput.newInstance();
			validComputTemp.setResult(vcount * 100 / count + "%");
			itemComputs.put(validComputTemp.getComputName() + "_" + key, validComputTemp);
		}
		
		computs.add(validComput);
		
		return itemComputs;
	}
	
	public List<SiteItemBean> getSiteItems() {
		return siteItems;
	}

}
